#

| Chapter 4 The Bourne Shell and Korn Shell |

## 4.2 Syntax

This subsection describes the many symbols peculiar to the Bourne and Korn shell. The topics are arranged as follows:

- Special files

- Filename metacharacters

- Quoting

- Command forms

- Redirection forms

- Coprocesses (Korn shell only)

### 4.2.1 Special Files

/etc/profile | Executed automatically at login.
$HOME/.profile | Executed automatically at login.
/etc/passwd | Source of home directories for ~`name` abbreviations.
$ENV | Specifies the name of a file to read when a new Korn shell is created.

### 4.2.2 Filename Metacharacters

* | Match any string of zero or more characters.
? | Match any single character.
[`abc`...] | Match any one of the enclosed characters; a hyphen can be used to specify a range (e.g., a-z, A-Z, 0-9).
[!`abc`...] | Match any character `not` enclosed as above.

In the Korn shell:

?(`pattern`) | Match zero or one instance of `pattern`.
*(`pattern`) | Match zero or more instances of `pattern`.
+(`pattern`) | Match one or more instance of `pattern`.
@(`pattern`) | Match exactly one instance of `pattern`.
!(`pattern`) | Match any strings that don't contain `pattern`.
~ | HOME directory of the current user.
~`name` | HOME directory of user `name`.
~+ | Current working directory (PWD).
~- | Previous working directory (OLDPWD).

The `pattern` above can be a sequence of patterns separated by |, meaning that the match applies to any of the patterns. This extended syntax resembles that available to egrep and awk.

#### 4.2.2.1 Examples

>     $ ls new*	List new and new.1.
>     $ cat ch?	Match ch9 but not ch10.
>     $ vi [D-R]*	Match files that begin with uppercase D through R.
>     $ cp !(Junk*|Temp*)*.c ..	Korn shell only.  Copy C source files
>     		except for Junk and Temp files.

### 4.2.3 Quoting

Quoting disables a character's special meaning and allows it to be used literally, as itself. The following characters have special meaning to the Bourne and Korn shells:

; | Command separator.
& | Background execution.
( ) | Command grouping.
| | Pipe.
> < & | Redirection symbols.
* ? [ ] ~ + - @ ! | Filename metacharacters.
" ' \ | Used in quoting other characters.
` | Command substitution.
$ | Variable substitution (or command substitution).
newline space tab | Word separators.

The characters below can be used for quoting:

" "

  Everything between " and " is taken literally, except for the following characters that keep their special meaning:

  $

    Variable substitution will occur.

  `

    Command substitution will occur.

  "

    This marks the end of the double quote.

`' '`

  Everything between `'` and `'` is taken literally except for another `'`.

`\`

  The character following a \ is taken literally. Use within " " to escape ", $, and `. Often used to escape itself, spaces, or newlines.

#### 4.2.3.1 Examples

>     $ echo 'Single quotes "protect" double quotes'
>     Single quotes "protect" double quotes
>     $ echo "Well, isn't that \"special\"?"
>     Well, isn't that "special"?
>     $ echo "You have `ls|wc -l` files in `pwd`"
>     You have      43 files in /home/bob
>     $ echo "The value of \$x is $x"
>     The value of $x is 100

### 4.2.4 Command Forms

`cmd` & | Execute `cmd` in background.
`cmd1` ; `cmd2` | Command sequence; execute multiple `cmd`s on the same line.
(`cmd1` ; `cmd2`) | Subshell; treat `cmd1` and `cmd2` as a command group.
`cmd1` | `cmd2` | Pipe; use output from `cmd1` as input to `cmd2`.
`cmd1` ``cmd2`` | Command substitution; use `cmd2` output as arguments to `cmd1`.
`cmd1` $(`cmd2`) | Korn-shell command substitution; nesting is allowed.
`cmd1` && `cmd2` | AND; execute `cmd1` and then (if `cmd1` succeeds) `cmd2`.
`cmd1` || `cmd2` | OR; execute either `cmd1` or (if `cmd1` fails) `cmd2`.
{ `cmd1` ; `cmd2` } | Execute commands in the current shell.

#### 4.2.4.1 Examples

>     $ nroff file &	Format in the background.
>     $ cd; ls	Execute sequentially.
>     $ (date; who; pwd) > logfile	All output is redirected.
>     $ sort file | pr -3 | lp		Sort file, page output, then print.
>     $ vi `grep -l ifdef *.c`		Edit files found by grep.
>     $ egrep '(yes|no)' `cat list`	Specify a list of files to search.
>     $ egrep '(yes|no)' $(cat list)	Korn shell version of previous.
>     $ egrep '(yes|no)' $(<list)	Same, but faster.
>     $ grep XX file && lp file		Print file if it contains the pattern,
>     $ grep XX file || echo "XX not found"	otherwise, echo an error message.

### 4.2.5 Redirection Forms

File |  | Common | Typical
--- | --- | --- | ---
Descriptor | Name | Abbreviation | Default
0 | Standard Input | stdin | Keyboard
1 | Standard Output | stdout | Terminal
2 | Standard Error | stderr | Terminal

The usual input source or output destination can be changed as follows:

#### 4.2.5.1 Simple Redirection

`cmd` > `file` | Send output of `cmd` to `file` (overwrite).
`cmd` >> `file` | Send output of `cmd` to `file` (append).
`cmd` < `file` | Take input for `cmd` from `file`.
`cmd` << `text` | Read standard input up to a line identical to `text` (`text` can be stored in a shell variable). Input is usually typed on the screen or in the shell program. Commands that typically use this syntax include cat, echo, ex, and sed. (If <<- is used, leading tabs are ignored when comparing input with end-of-input `text` marker.) This command form is sometimes called a "Here" document.

#### 4.2.5.2 Redirection Using File Descriptors

`cmd` >&`n` | Send `cmd` output to file descriptor `n`.
`cmd` `m`>&`n` | Same, except that output that would normally go to file descriptor `m` is sent to file descriptor `n` instead.
`cmd` >&- | Close standard output.
`cmd` <&`n` | Take input for `cmd` from file descriptor `n`.
`cmd` `m`<&`n` | Same, except that input that would normally come from file descriptor `m` comes from file descriptor `n` instead.
`cmd` <&- | Close standard input.

#### 4.2.5.3 Multiple Redirection

`cmd` 2>`file` | Send standard error to `file`; standard output remains the same (e.g., the screen).
`cmd` > `file` 2>&1 | Send both standard error and standard output to `file`.
(`cmd` > `f1`) 2>`f2` | Send standard output to file `f1`; standard error to file `f2`.
`cmd` | tee `files` | Send output of `cmd` to standard output (usually the terminal) and to `files`. (See the example in Section 2 under tee.)

No space should appear between file descriptors and a redirection symbol; spacing is optional in the other cases.

#### 4.2.5.4 Examples

>     $ cat part1 > book
>     $ cat part2 part3 >> book
>     $ mail tim < report
>     $ sed 's/^/XX /g' << END_ARCHIVE
>     > This is often how a shell archive is "wrapped",
>     > bundling text for distribution.  You would normally
>     > run sed from a shell program, not from the command line.
>     > END_ARCHIVE
>     XX This is often how a shell archive is "wrapped",
>     XX bundling text for distribution.  You would normally
>     XX run sed from a shell program, not from the command line.

To redirect standard output to standard error:

>     $ echo "Usage error:  see administrator" 1>&2

The following command will send output (files found) to filelist and send error messages (inaccessible files) to file no_access:

>     $ (find / -print > filelist) 2>no_access

### 4.2.6 Coprocesses

Coprocesses are a feature of the Korn shell only.

`cmd1` | `cmd2` |& | Coprocess; execute the pipeline in the background. The shell sets up a two-way pipe, allowing redirection of both standard input and standard output.
read -p `var` | Read coprocess input into variable `var`.
print -p `string` | Write `string` to the coprocess.
`cmd` <&p | Take input for `cmd` from the coprocess.
`cmd` >&p | Send output of `cmd` to the coprocess.

#### 4.2.6.1 Examples

>     ed - memo |&	Start coprocess.
>     print -p /word/	Send ed command to coprocess.
>     read -p search	Read output of ed command into variable search.
>     print "$search"	Show the line on standard output.
>     A word to the wise.

4.1 Overview of Features |  | 4.3 Variables